package com.japhet.paypaldemo.controller;

import com.japhet.paypaldemo.config.PaypalPaymentIntent;
import com.japhet.paypaldemo.config.PaypalPaymentMethod;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@RestController
public class PayPalController {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private APIContext apiContext;

    @Value("${pay.paypal.PAYPAL_SUCCESS_PAGE}")
    private String PAYPAL_SUCCESS_PAGE;
    @Value("${pay.paypal.PAYPAL_CANCEL_PAGE}")
    private String PAYPAL_CANCEL_PAGE;

    @Value("${pay.paypal.PAYPAL_SUCCESS_URL}")
    private String PAYPAL_SUCCESS_URL;

    @Value("${pay.paypal.PAYPAL_CANCEL_URL}")
    private String PAYPAL_CANCEL_URL;

    @PostMapping("/payPal")
    public String toPay(){
        //我这里写死了 1
        BigDecimal payAmount = new BigDecimal(1);
        try {
            Payment payment = createPayment(
                    payAmount,
                    "USD",
                    PaypalPaymentMethod.paypal,
                    PaypalPaymentIntent.sale,
                    "购买商品信息~",
                    PAYPAL_CANCEL_URL,
                    PAYPAL_SUCCESS_URL);
            log.info("=========================================");
            log.info(payment.toString());
            log.info("=========================================");
            //保存paypal预支付信息

            //修改订单金额 & 支付的流水号

            log.info("支付金额："+payAmount);
            log.info("订单号："+payment.getId());

            for (Links links : payment.getLinks()) {
                if (links.getRel().equals("approval_url")) {
                    return links.getHref();
                }
            }
        } catch (PayPalRESTException e) {
            //保存paypal预支付异常信息 .......
            log.error(e.getMessage());
        }
        return "index";
    }


    /**
     * PayPal 支付成功 回调
     * @param response
     * @param paymentId
     * @param payerId
     */
    @GetMapping("/callback/success")
    public void successPay(HttpServletResponse response, @RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId) {
        log.info("================================payPal 回调成功==================================="+paymentId);
        log.info("================================payPal 回调成功==================================="+payerId);
        try {
            Payment payment = executePayment(paymentId,payerId);

            log.info("================================payment===================================");
            log.info(payment.toString());
            log.info("================================payment===================================");
            if (payment.getState().equals("approved")) {
                //修改订单状态

                response.sendRedirect(PAYPAL_SUCCESS_PAGE);
            }else{
                response.sendRedirect(PAYPAL_CANCEL_PAGE);
            }

        } catch (PayPalRESTException e) {
            log.info("!!!!!!!!!!!!!!支付回调失败 异常!!!!!!!!!!!!!!");
            log.error(e.getMessage());
            log.info("!!!!!!!!!!!!!!支付回调失败 异常!!!!!!!!!!!!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * paypal 回调 取消支付
     * @param response
     * @throws IOException
     */
    @GetMapping("/callback/cancel")
    public void cancelPay(HttpServletResponse response) throws IOException {
        log.info("================================payPal 取消支付===================================");
        log.info("================================payPal 取消支付===================================");
        response.sendRedirect(PAYPAL_CANCEL_PAGE);
    }


    @RequestMapping("/success")
    public String success(){
        return "success";
    }

    @RequestMapping("/cancel")
    public String cancel(){
        return "cancel";
    }

    /**
     *
     * @param total
     * @param currency
     * @param method
     * @param intent
     * @param description
     * @param cancelUrl
     * @param successUrl
     * @return
     * @throws PayPalRESTException
     */
    public Payment createPayment(BigDecimal total, String currency, PaypalPaymentMethod method, PaypalPaymentIntent intent,
                                 String description, String cancelUrl, String successUrl) throws PayPalRESTException {
        Amount amount = new Amount();
        amount.setCurrency(currency);
        amount.setTotal(String.format("%.2f", total));

        Transaction transaction = new Transaction();
        transaction.setDescription(description);
        transaction.setAmount(amount);

        List<Transaction> transactions = new ArrayList<>();
        transactions.add(transaction);

        Payer payer = new Payer();
        payer.setPaymentMethod(method.toString());

        Payment payment = new Payment();
        payment.setIntent(intent.toString());
        payment.setPayer(payer);
        payment.setTransactions(transactions);
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(cancelUrl);
        redirectUrls.setReturnUrl(successUrl);
        payment.setRedirectUrls(redirectUrls);

        return payment.create(apiContext);
    }

    /**
     *
     * @param paymentId
     * @param payerId
     * @return
     * @throws PayPalRESTException
     */
    public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {
        Payment payment = new Payment();
        payment.setId(paymentId);
        PaymentExecution paymentExecute = new PaymentExecution();
        paymentExecute.setPayerId(payerId);
        return payment.execute(apiContext, paymentExecute);
    }

}
